/**
  ******************************************************************************
  * @file    zqlink.h
  * @author  Aizbot
  * @brief   xxx.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2023 Aizbot.
  * All rights reserved.</center></h2>
  *
  * http://www.aizbot.com
  *
  ******************************************************************************
  */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __ZQLINK_H
#define __ZQLINK_H

#ifdef __cplusplus
 extern "C" {
#endif

/** 
  * @Aizbot: https://gitee.com/aizbot/zqlink
  */  

/* Includes ------------------------------------------------------------------*/
#include "common.h"
#include "zqfifo.h"

/* Exported constants --------------------------------------------------------*/
#define ZQLINK_PAYLOAD_LEN_SHORT 	256  	/* < Maximum payload length, 0-255 */
#define ZQLINK_PAYLOAD_LEN_LONG 	1024  	/* < Maximum payload length, 0-65535 */

#define ZQLINK_HEADER_BYTES 		6 	 /* Length of all header bytes */
#define ZQLINK_CHECKSUM_BYTES 		3	 /* Length of check: xor + crc16 */
#define ZQLINK_EXTEND_BYTES 		8	 /* Maybe Tail */
#define ZQLINK_OTHER_BYTES 			(ZQLINK_HEADER_BYTES + ZQLINK_CHECKSUM_BYTES + ZQLINK_EXTEND_BYTES)

#define ZQLINK_PACKET_LEN_SHORT 	(ZQLINK_PAYLOAD_LEN_SHORT + ZQLINK_OTHER_BYTES) /* Maximum packet length */
#define ZQLINK_PACKET_LEN_LONG 		(ZQLINK_PAYLOAD_LEN_LONG  + ZQLINK_OTHER_BYTES) /* Maximum packet length */

#define ZQLINK_STX1					0xAA
#define ZQLINK_STX2_A1				0xF1
#define ZQLINK_STX2_A2				0xF2
#define ZQLINK_STX2_A3				0xF3
#define ZQLINK_STX2_A4				0xF4

#define ZQLINK_TAIL					0xFE
#define ZQLINK_TAIL_NOTUSE			0
#define ZQLINK_TAIL_USE				1

#define ZQLINK_OVERFLOW_TIME		10000

/* Exported macro ------------------------------------------------------------*/
#ifdef ZQLINK_C
#define ZQLINK_EXT
#else
#define ZQLINK_EXT extern
#endif

/* Exported types ------------------------------------------------------------*/
/** 
  * @brief  xxx
  */  
typedef enum
{
	ZQLINK_VERSION_A1 = ZQLINK_STX2_A1,
	ZQLINK_VERSION_A2 = ZQLINK_STX2_A2,	
	ZQLINK_VERSION_A3 = ZQLINK_STX2_A3,
	ZQLINK_VERSION_A4 = ZQLINK_STX2_A4
}Zqlink_Version_t;

/** 
  * @brief  xxx
  */  
typedef enum 
{
	ZQLINK_STATE_STX1,
	ZQLINK_STATE_STX2,	
	ZQLINK_STATE_LEN1,
	ZQLINK_STATE_LEN2,
	ZQLINK_STATE_SEQ,
	ZQLINK_STATE_SYSID,
	ZQLINK_STATE_COMPID,
	ZQLINK_STATE_MSGCMD,
	ZQLINK_STATE_PAYLOAD,
	ZQLINK_STATE_CHECKSUM,
	ZQLINK_STATE_TAIL
}Zqlink_State_t;

/** 
  * @brief  xxx
  */  
typedef struct 
{
	Zqlink_Version_t ver;
	uint16_t length;
	uint8_t seq;
	uint8_t sysid;
	uint8_t compid;
	union {
		uint8_t cmd;
		struct {
			uint8_t subcmd: 4;	/* low bits */
			uint8_t maincmd: 4;	/* high bits */
		};
	}msgid;
	uint8_t *data;	/* data[ZQLINK_PAYLOAD_LEN] */
	uint8_t checksum;
	uint8_t tail;
}Zqlink_Msg_t;

/** 
  * @brief  xxx
  */  
typedef struct 
{
	Zqlink_Msg_t 	msg;
	Zqlink_State_t state;
	uint8_t 		dev;
	uint16_t 		index;
	TIMER_t			timeout;

	void (*Api_RecSuccess)(Zqlink_Msg_t *message, uint8_t device);
	void (*Api_RecError)  (Zqlink_Msg_t *message, uint8_t device);
}Zqlink_t;

/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
ZQLINK_EXT uint8_t  Zqlink_Check(Zqlink_Msg_t *msg);
ZQLINK_EXT void 	Zqlink_Packing(Zqlink_Msg_t *msg, Zqfifo_t *fifo);
ZQLINK_EXT void 	Zqlink_Unpack(Zqfifo_t *fifo, Zqlink_t *handle);

#ifdef __cplusplus
}
#endif

#endif /* __ZQLINK_H */

/************************ (C) COPYRIGHT Aizbot ********************************/
